Certain types of event channel are now auto-bound to vcpu0 by Xen.
authorsos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Fri, 8 Jul 2005 15:35:43 +0000 (15:35 +0000)
committersos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Fri, 8 Jul 2005 15:35:43 +0000 (15:35 +0000)
Make sure that xenolinux agrees with this.

linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c
linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c

index 4798f1d4ec7d086560baa1e23aae440c75a645a2..215cff15b3402db01d95c8c8975e54818f886c37 100644 (file)
@@ -1533,13 +1533,13 @@ void __init smp_intr_init(void)
        int cpu = smp_processor_id();
 
        per_cpu(resched_irq, cpu) =
-               bind_ipi_to_irq(RESCHEDULE_VECTOR);
+               bind_ipi_on_cpu_to_irq(RESCHEDULE_VECTOR);
        sprintf(resched_name[cpu], "resched%d", cpu);
        BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt,
                           SA_INTERRUPT, resched_name[cpu], NULL));
 
        per_cpu(callfunc_irq, cpu) =
-               bind_ipi_to_irq(CALL_FUNCTION_VECTOR);
+               bind_ipi_on_cpu_to_irq(CALL_FUNCTION_VECTOR);
        sprintf(callfunc_name[cpu], "callfunc%d", cpu);
        BUG_ON(request_irq(per_cpu(callfunc_irq, cpu),
                           smp_call_function_interrupt,
index c1cfb82dbdde1f89eeda4ddd2f48c4c26524fa9d..733103f475b1edd2ec60a5efe6fcd3e682298639 100644 (file)
@@ -491,6 +491,8 @@ void ctrl_if_resume(void)
          * pick up its end of the event channel from 
          */
         evtchn_op_t op;
+       extern void bind_evtchn_to_cpu(unsigned port, unsigned cpu);
+
         op.cmd = EVTCHNOP_bind_interdomain;
         op.u.bind_interdomain.dom1 = DOMID_SELF;
         op.u.bind_interdomain.dom2 = DOMID_SELF;
@@ -500,6 +502,7 @@ void ctrl_if_resume(void)
             BUG();
         xen_start_info.domain_controller_evtchn = op.u.bind_interdomain.port1;
         initdom_ctrlif_domcontroller_port   = op.u.bind_interdomain.port2;
+       bind_evtchn_to_cpu(op.u.bind_interdomain.port1, 0);
     }
 
     /* Sync up with shared indexes. */
index b293eee001d189888a5115d744443780eff9bc29..7db8ee5e8d706f36546ef3c7abae4eea8aca09c3 100644 (file)
@@ -86,7 +86,7 @@ static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32];
      cpu_evtchn_mask[cpu][idx] &                \
      ~(sh)->evtchn_mask[idx])
 
-static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
 {
     clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
     set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
@@ -99,8 +99,9 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
     ((sh)->evtchn_pending[idx] &                \
      ~(sh)->evtchn_mask[idx])
 
-#define bind_evtchn_to_cpu(chn,cpu) ((void)0)
-
+void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+{
+}
 #endif
 
 /* Upcall to generic IRQ layer. */
@@ -228,6 +229,13 @@ void unbind_virq_from_irq(int virq)
         if ( HYPERVISOR_event_channel_op(&op) != 0 )
             panic("Failed to unbind virtual IRQ %d\n", virq);
 
+       /* This is a slight hack.  Interdomain ports can be allocated
+          directly by userspace, and at that point they get bound by
+          Xen to vcpu 0.  We therefore need to make sure that if we
+          get an event on an event channel we don't know about vcpu 0
+          handles it.  Binding channels to vcpu 0 when closing them
+          achieves this. */
+       bind_evtchn_to_cpu(evtchn, 0);
         evtchn_to_irq[evtchn] = -1;
         irq_to_evtchn[irq]    = -1;
         per_cpu(virq_to_irq, cpu)[virq]     = -1;
@@ -320,6 +328,8 @@ void unbind_ipi_from_irq(int ipi)
        if ( HYPERVISOR_event_channel_op(&op) != 0 )
            panic("Failed to unbind virtual IPI %d on cpu %d\n", ipi, cpu);
 
+       /* See comments in unbind_virq_from_irq */
+       bind_evtchn_to_cpu(evtchn, 0);
         evtchn_to_irq[evtchn] = -1;
         irq_to_evtchn[irq]    = -1;
        per_cpu(ipi_to_evtchn, cpu)[ipi] = 0;
@@ -474,6 +484,7 @@ static unsigned int startup_pirq(unsigned int irq)
 
     pirq_query_unmask(irq_to_pirq(irq));
 
+    bind_evtchn_to_cpu(evtchn, 0);
     evtchn_to_irq[evtchn] = irq;
     irq_to_evtchn[irq]    = evtchn;
 
@@ -499,6 +510,7 @@ static void shutdown_pirq(unsigned int irq)
     if ( HYPERVISOR_event_channel_op(&op) != 0 )
         panic("Failed to unbind physical IRQ %d\n", irq);
 
+    bind_evtchn_to_cpu(evtchn, 0);
     evtchn_to_irq[evtchn] = -1;
     irq_to_evtchn[irq]    = -1;
 }
@@ -598,6 +610,7 @@ void irq_resume(void)
         evtchn = op.u.bind_virq.port;
         
         /* Record the new mapping. */
+       bind_evtchn_to_cpu(evtchn, 0);
         evtchn_to_irq[evtchn] = irq;
         irq_to_evtchn[irq]    = evtchn;